//
//  LowHighWeatherTemperaturesView.swift
//  SwiftWeather
//
//  Created by shen on 2023/8/28.
//

import UIKit
import Combine

final class LowHighWeatherTemperaturesViewModel {
    // MARK: Properties

    @Published private var day: Day?
    @Published private var temperatureUnits: TemperatureUnits

    var minTemperaturePublisher: AnyPublisher<Temperature, Never> {
        $day.combineLatest($temperatureUnits)
            .compactMap { day, units in
                guard let day else { return nil }
                return (day, units)
            }
            .flatMap { day, units in
                Just(day).mapToTemperature(type: .low, in: units)
            }
            .eraseToAnyPublisher()
    }

    var maxTemperaturePublisher: AnyPublisher<Temperature, Never> {
        $day.combineLatest($temperatureUnits)
            .compactMap { day, units in
                guard let day else { return nil }
                return (day, units)
            }
            .flatMap { day, units in
                Just(day).mapToTemperature(type: .high, in: units)
            }
            .eraseToAnyPublisher()
    }

    // MARK: - Initialization

    init(day: Day? = nil, temperatureUnits: TemperatureUnits) {
        self.day = day
        self.temperatureUnits = temperatureUnits
    }
}

final class LowHighWeatherTemperaturesView: BaseView, ViewModelable {
    typealias ViewModel = LowHighWeatherTemperaturesViewModel

    // MARK: Properties

    var viewModel: ViewModel! {
        didSet {
            setupTemperatureView(lowTemperatureView, withPublisher: viewModel.minTemperaturePublisher)
            setupTemperatureView(highTemperatureView, withPublisher: viewModel.maxTemperaturePublisher)
        }
    }

    private var cancellables = Set<AnyCancellable>()

    // MARK: - Views

    private lazy var mainHStack: UIStackView = .init(
        arrangedSubviews: [lowTemperatureView, highTemperatureView],
        axis: .horizontal,
        spacing: 60
    )

    private lazy var lowTemperatureView: TemperatureView = {
        let temperatureView = TemperatureView(title: "LOW")
        temperatureView.alpha = 0.6
        return temperatureView
    }()

    private lazy var highTemperatureView = TemperatureView(title: "HIGH")

    // MARK: - Methods

    override func configureAppearance() {
        backgroundColor = .clear
    }

    override func setupViews() {
        addSubview(mainHStack)
    }

    override func constraintViews() {
        mainHStack.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            mainHStack.topAnchor.constraint(equalTo: topAnchor, constant: 20),
            mainHStack.centerXAnchor.constraint(equalTo: centerXAnchor),
            mainHStack.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -20),
        ])
    }
}

// MARK: - Private methods

private extension LowHighWeatherTemperaturesView {
    func setupTemperatureView<P: Publisher>(_ view: TemperatureView, withPublisher publisher: P) where P.Output == Temperature, P.Failure == Never {
        publisher
            .sink { view.setupViews(withTemperature: $0) }
            .store(in: &cancellables)
    }
}
